package controller

import (
	"context"
	"fmt"
	"net/http"
	"strconv"
	"time"

	"github.com/dgrijalva/jwt-go/v4"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"golang.org/x/exp/rand"

	"2106a-zg5/work/day15/user_api/global"
	"2106a-zg5/work/day15/user_api/utils"
	"2106a-zg5/work/day15/user_srv/proto"
)

// UserLoginByUp 用户密码登录
func UserLoginByUp(c *gin.Context) {
	username := c.PostForm("username")
	password := c.PostForm("password")
	captchaId := c.PostForm("captcha_id")
	captcha := c.PostForm("captcha")
	fmt.Println(captchaId, captcha)
	//验证图形验证码是否正确
	//第三个参数clear清除，是否用完就失效
	//verify := store.Verify(captchaId, captcha, true)
	//if !verify {
	//	c.JSON(http.StatusBadRequest, gin.H{
	//		"code":    10003,
	//		"message": "图形验证码错误",
	//		"data":    nil,
	//	})
	//	return
	//}

	//调用方法
	res, err := global.UserService.UserLogin(context.Background(), &proto.UserLoginReq{
		Username: username,
		Password: password,
	})
	if err != nil {
		c.JSON(http.StatusBadRequest, &gin.H{
			"msg":  err.Error(),
			"code": 1002,
			"data": nil,
		})
		return
	}

	//创建成功 生成token
	token, err := utils.CreateToken(&utils.MyCustomClaims{
		//存储用户ID
		UserId: res.User.Id,
		//过期时间
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + 86400)),
		},
	})
	//判断是否生成token
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{
			"Data":    nil,
			"message": err.Error(),
			"code":    1003,
		})
		return
	}
	//zap.S().Info("登陆成功")
	c.JSON(http.StatusOK, &gin.H{
		"msg":  "success",
		"code": 1,
		"data": map[string]interface{}{
			"userInfo": res,
			"token":    token,
		},
	})
}

// UserLoginByMb 手机号登录
func UserLoginByMb(c *gin.Context) {
	mobile := c.PostForm("mobile")
	password := c.PostForm("password")
	captchaId := c.PostForm("captcha_id")
	captcha := c.PostForm("captcha")
	fmt.Println(captchaId, captcha)
	//验证图形验证码是否正确
	//第三个参数clear清除，是否用完就失效
	verify := store.Verify(captchaId, captcha, true)
	if !verify {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    10003,
			"message": "图形验证码错误",
			"data":    nil,
		})
		return
	}

	//调用方法
	res, err := global.UserService.UserLoginByMb(context.Background(), &proto.UserLoginByMbReq{
		Mobile:   mobile,
		Password: password,
	})
	if err != nil {
		c.JSON(http.StatusBadRequest, &gin.H{
			"msg":  err.Error(),
			"code": 1002,
			"data": nil,
		})
		return
	}

	//创建成功 生成token
	token, err := utils.CreateToken(&utils.MyCustomClaims{
		//存储用户ID
		UserId: res.User.Id,
		//过期时间
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + 86400)),
		},
	})
	//判断是否生成token
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{
			"Data":    nil,
			"message": err.Error(),
			"code":    1003,
		})
		return
	}
	zap.S().Info("登陆成功")
	c.JSON(http.StatusOK, &gin.H{
		"msg":  "success",
		"code": 1,
		"data": map[string]interface{}{
			"userInfo": res,
			"token":    token,
		},
	})
}

// UserUpdatePwd 修改密码
func UserUpdatePwd(c *gin.Context) {
	id := c.PostForm("id")
	idInt, _ := strconv.Atoi(id)
	password := c.PostForm("password")

	pwd, err := global.UserService.UserUpPwd(context.Background(), &proto.UserUpPwdReq{
		Id:       int64(idInt),
		Password: password,
	})
	if err != nil {
		c.JSON(http.StatusBadRequest, &gin.H{
			"msg":  err.Error(),
			"code": 1003,
			"data": nil,
		})
		return
	}
	c.JSON(http.StatusOK, &gin.H{
		"msg":  "success",
		"code": 1,
		"data": pwd,
	})
	return
}

// UserUploadPhoto 上传头像
func UserUploadPhoto(c *gin.Context) {
	id := c.PostForm("id")
	idInt, _ := strconv.Atoi(id)
	f, err := c.FormFile("file")
	if err != nil {
		if err != nil {
			zap.S().Info("文件上传失败")
			c.JSON(http.StatusBadRequest, &gin.H{
				"msg":  err.Error(),
				"code": 1002,
				"data": nil,
			})
			return
		}
	}
	path := utils.Upload(f)
	res, err := global.UserService.UserUpPhoto(context.Background(), &proto.UserUpPhotoReq{
		Id:       int64(idInt),
		PhotoUrl: path,
	})
	if err != nil {
		c.JSON(http.StatusBadRequest, &gin.H{
			"msg":  err.Error(),
			"code": 1004,
			"data": nil,
		})
		return
	}
	c.JSON(http.StatusOK, &gin.H{
		"msg":  "success",
		"code": 1,
		"data": res,
	})
	return

}

// UserRegister 注册
func UserRegister(c *gin.Context) {

	username := c.PostForm("username")
	password := c.PostForm("password")
	email := c.PostForm("email")
	mobile := c.PostForm("mobile")

	res, err := global.UserService.UserReg(context.Background(), &proto.UserRegReq{
		Username: username,
		Password: password,
		Email:    email,
		Mobile:   mobile,
	})
	if err != nil {
		c.JSON(http.StatusBadRequest, &gin.H{
			"msg":  err.Error(),
			"code": 1002,
			"data": nil,
		})
		return
	}
	//创建成功 生成token
	token, err := utils.CreateToken(&utils.MyCustomClaims{
		//存储用户ID
		UserId: res.User.Id,
		//过期时间
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Unix() + 86400)),
		},
	})
	//判断是否生成token
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{
			"Data":    nil,
			"message": err.Error(),
			"code":    1003,
		})
		return
	}

	c.JSON(http.StatusOK, &gin.H{
		"msg":  "success",
		"code": 1,
		"data": map[string]interface{}{
			"userInfo": res,
			"token":    token,
		},
	})

}

// SendSms 发送验证码
func SendSms(c *gin.Context) {
	mobile := c.PostForm("mobile")
	code := GetCode()

	if !utils.IhuY(mobile, code) {
		c.JSON(http.StatusBadRequest, &gin.H{
			"msg":  "发送失败",
			"code": 1001,
			"data": nil,
		})
		return
	}
	c.JSON(http.StatusBadRequest, &gin.H{
		"msg":  "发送成功",
		"code": 0,
		"data": code,
	})
}

// UserInfoList 用户列表展示
func UserInfoList(c *gin.Context) {
	page := c.Query("page")
	pageSize := c.Query("page_size")
	pageInt, _ := strconv.Atoi(page)
	pageSizeInt, _ := strconv.Atoi(pageSize)

	res, err := global.UserService.UserInFoList(context.Background(), &proto.UserInFoListReq{
		Page:     int64(pageInt),
		PageSize: int64(pageSizeInt),
	})
	if err != nil {
		if err != nil {
			c.JSON(http.StatusBadRequest, &gin.H{
				"msg":  err.Error(),
				"code": 1002,
				"data": nil,
			})
			return
		}
	}

	c.JSON(http.StatusOK, &gin.H{
		"msg":  "success",
		"code": 200,
		"data": map[string]interface{}{
			"data":  res.User,
			"total": res.Total,
		},
	})
}

// GetCode 发送验证码
func GetCode() int {
	str := ""
	for i := 1; i <= 4; i++ {
		str += fmt.Sprintf("%d", rand.Intn(10))
	}
	code, _ := strconv.Atoi(str)
	return code
}
